{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is a less verbose notebook intended to be used for technical demos.\n",
    "\n",
    "# SETUP\n",
    "from opendp.trans import *\n",
    "from opendp.meas import *\n",
    "from opendp.comb import *\n",
    "\n",
    "from opendp.mod import enable_features\n",
    "\n",
    "enable_features(\"floating-point\", \"contrib\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 0]\n"
     ]
    }
   ],
   "source": [
    "# PARSING DATA\n",
    "data = \"\"\"\n",
    "1\n",
    "2\n",
    "3\n",
    "4\n",
    "5\n",
    "x\n",
    "\"\"\"[1:]\n",
    "\n",
    "# Parse lines as integers\n",
    "preprocessor = (\n",
    "    make_split_lines() >>\n",
    "    make_cast(TIA=str, TOA=int) >>\n",
    "    make_impute_constant(constant=0)\n",
    ")\n",
    "res = preprocessor(data)\n",
    "print(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "outputs": [],
   "source": [
    "# STABILITY RELATION\n",
    "assert preprocessor.check(d_in=2, d_out=2)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.0, 2.0, 3.0, 4.0, 5.0, 0.0]\n"
     ]
    }
   ],
   "source": [
    "# Parse lines as floats\n",
    "preprocessor = (\n",
    "    make_split_lines() >>\n",
    "    make_cast(TIA=str, TOA=float) >>\n",
    "    make_impute_constant(constant=0.)\n",
    ")\n",
    "res = preprocessor(data)\n",
    "print(res)\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "# LOADING DATA\n",
    "data = \"\"\"\n",
    "a\n",
    "b\n",
    "c\n",
    "d\n",
    "e\n",
    "\"\"\"[1:]\n",
    "\n",
    "# Split file by line\n",
    "count = make_split_lines() >> make_count(TIA=str)\n",
    "res = count(data)\n",
    "print(res)\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['1', '2', '3', '4', '5']\n"
     ]
    }
   ],
   "source": [
    "# DATAFRAMES\n",
    "data = \"\"\"\n",
    "ant, 1, 10.0\n",
    "bat, 2, 20.0\n",
    "cat, 3, 30.0\n",
    "foo, 4, 40.0\n",
    "bar, 5, 50.0\n",
    "\"\"\"[1:]\n",
    "# Split a dataframe\n",
    "split_dataframe = make_split_dataframe(separator=\",\", col_names=[\"A\", \"B\", \"C\"])\n",
    "\n",
    "# Chain splitting and column selection\n",
    "split_and_select = split_dataframe >> make_select_column(key=\"B\", TOA=str)\n",
    "\n",
    "# look at column 1\n",
    "res = split_and_select(data)\n",
    "print(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "# SIMPLE OPERATIONS\n",
    "data = [1., 2., 3., 4., 5.]\n",
    "\n",
    "# Split and parse lines, chain into sum query\n",
    "query = (\n",
    "    make_clamp(bounds=(0., 10.)) >>\n",
    "    make_bounded_sum(bounds=(0., 10.))\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "13.748840194597886\n"
     ]
    }
   ],
   "source": [
    "# CHECK PRIVACY\n",
    "query_laplace = query >> make_base_laplace(scale=1.)\n",
    "max_user_contribution = 1\n",
    "budget = 10.\n",
    "assert query_laplace.check(d_in=max_user_contribution, d_out=budget)\n",
    "print(query_laplace(data))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "14.401209981614546\n"
     ]
    }
   ],
   "source": [
    "# TRANSFORMATION REUSE\n",
    "query_gaussian = query >> make_base_gaussian(scale=1.)\n",
    "print(query_gaussian(data))\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MASKED ERROR: 'AnyObject'\n",
      "using string fallback\n",
      "((16, 49.78050314854861), 4)\n"
     ]
    }
   ],
   "source": [
    "# PUTTING IT ALL TOGETHER\n",
    "data = \"\"\"\n",
    "ant, 1, 10.0\n",
    "bat, 2, 20.0\n",
    "cat, 3, 30.0\n",
    "foo, 4, 40.0\n",
    "bar, 5, 50.0\n",
    "\"\"\"[1:]\n",
    "\n",
    "parse_dataframe = make_split_dataframe(separator=\",\", col_names=[\"A\", \"B\", \"C\"])\n",
    "\n",
    "noisy_sum_col_1 = (\n",
    "    make_select_column(key=\"B\", TOA=str) >>\n",
    "    make_cast_default(TIA=str, TOA=int) >>\n",
    "    make_clamp((0, 10)) >>\n",
    "    make_bounded_sum(bounds=(0, 10)) >>\n",
    "    make_base_geometric(scale=1.0)\n",
    ")\n",
    "\n",
    "noisy_sum_col_2 = (\n",
    "    make_select_column(key=\"C\", TOA=str) >>\n",
    "    make_cast_default(TIA=str, TOA=float) >>\n",
    "    make_clamp(bounds=(0., 10.)) >>\n",
    "    make_bounded_sum(bounds=(0., 10.)) >>\n",
    "    make_base_laplace(scale=1.0)\n",
    ")\n",
    "\n",
    "noisy_count = (\n",
    "    make_select_column(key=\"A\", TOA=str) >>\n",
    "    make_count(TIA=str) >>\n",
    "    make_base_geometric(scale=1.0)\n",
    ")\n",
    "\n",
    "# Compose & chain\n",
    "composition = make_basic_composition(make_basic_composition(\n",
    "    noisy_sum_col_1, noisy_sum_col_2), noisy_count)\n",
    "\n",
    "everything = parse_dataframe >> composition\n",
    "\n",
    "print(everything(data))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}